package com.my.lucky.service;

import com.my.lucky.model.Stock;

import java.util.List;

public class TradeSignal {
    // 买入信号阈值
    private static final double OVERSOLD_RSI = 30.0;
    private static final double GOLDEN_CROSS_THRESHOLD = 0.0;
    private static final int MA_SHORT = 5;
    private static final int MA_LONG = 20;

    /**
     * 判断是否为买入信号
     * 条件：
     * 1. RSI低于30，超卖区间
     * 2. 5日均线上穿20日均线（黄金交叉）
     * 3. 成交量放大
     */
    public static boolean isBuySignal(List<Stock> stockHistory) {
        if (stockHistory == null || stockHistory.size() < MA_LONG + 1) {
            return false;
        }

        // 计算RSI
        double rsi = calculateRSI(stockHistory);

        // 计算均线
        double shortMA = calculateMA(stockHistory, MA_SHORT);
        double longMA = calculateMA(stockHistory, MA_LONG);
        double prevShortMA = calculatePrevMA(stockHistory, MA_SHORT);
        double prevLongMA = calculatePrevMA(stockHistory, MA_LONG);

        // 计算成交量变化
        double volumeChange = calculateVolumeChange(stockHistory);

        // 判断买入条件
        boolean isOversold = rsi < OVERSOLD_RSI;
        boolean isGoldenCross = prevShortMA <= prevLongMA && shortMA > longMA;
        boolean isVolumeIncreased = volumeChange > 1.5; // 成交量放大50%

        return isOversold && isGoldenCross && isVolumeIncreased;
    }

    /**
     * 判断是否为卖出信号
     * 条件：
     * 1. RSI高于70，超买区间
     * 2. 5日均线下穿20日均线（死亡交叉）
     * 3. 股价创近期新高后回落
     */
    public static boolean isSellSignal(List<Stock> stockHistory) {
        if (stockHistory == null || stockHistory.size() < MA_LONG + 1) {
            return false;
        }

        // 计算RSI
        double rsi = calculateRSI(stockHistory);

        // 计算均线
        double shortMA = calculateMA(stockHistory, MA_SHORT);
        double longMA = calculateMA(stockHistory, MA_LONG);
        double prevShortMA = calculatePrevMA(stockHistory, MA_SHORT);
        double prevLongMA = calculatePrevMA(stockHistory, MA_LONG);

        // 判断是否创新高后回落
        boolean isPriceDropAfterHigh = isPriceDropAfterHigh(stockHistory);

        // 判断卖出条件
        boolean isOverbought = rsi > 70;
        boolean isDeathCross = prevShortMA >= prevLongMA && shortMA < longMA;

        return isOverbought && isDeathCross && isPriceDropAfterHigh;
    }

    // 计算RSI指标
    private static double calculateRSI(List<Stock> stockHistory) {
        int period = 14; // 传统RSI周期为14
        if (stockHistory.size() < period + 1) {
            return 50.0; // 默认值
        }

        double sumGain = 0.0;
        double sumLoss = 0.0;

        for (int i = stockHistory.size() - period; i < stockHistory.size(); i++) {
            double change = stockHistory.get(i).getClose() - stockHistory.get(i - 1).getClose();
            if (change > 0) {
                sumGain += change;
            } else {
                sumLoss -= change;
            }
        }

        if (sumLoss == 0) {
            return 100.0;
        }

        double rs = sumGain / sumLoss;
        return 100.0 - (100.0 / (1 + rs));
    }

    // 计算移动平均线
    private static double calculateMA(List<Stock> stockHistory, int period) {
        if (stockHistory.size() < period) {
            return 0.0;
        }

        double sum = 0.0;
        for (int i = stockHistory.size() - period; i < stockHistory.size(); i++) {
            sum += stockHistory.get(i).getClose();
        }
        return sum / period;
    }

    // 计算前一天的移动平均线
    private static double calculatePrevMA(List<Stock> stockHistory, int period) {
        if (stockHistory.size() < period + 1) {
            return 0.0;
        }

        double sum = 0.0;
        for (int i = stockHistory.size() - period - 1; i < stockHistory.size() - 1; i++) {
            sum += stockHistory.get(i).getClose();
        }
        return sum / period;
    }

    // 计算成交量变化
    private static double calculateVolumeChange(List<Stock> stockHistory) {
        if (stockHistory.size() < 2) {
            return 1.0;
        }

        double currentVolume = stockHistory.get(stockHistory.size() - 1).getVolume();
        double prevVolume = stockHistory.get(stockHistory.size() - 2).getVolume();

        return currentVolume / prevVolume;
    }

    // 判断是否创新高后回落
    private static boolean isPriceDropAfterHigh(List<Stock> stockHistory) {
        int period = 10; // 观察近10天的价格
        if (stockHistory.size() < period) {
            return false;
        }

        double currentPrice = stockHistory.get(stockHistory.size() - 1).getClose();
        double maxPrice = Double.MIN_VALUE;

        // 找出近期最高价
        for (int i = stockHistory.size() - period; i < stockHistory.size() - 1; i++) {
            maxPrice = Math.max(maxPrice, stockHistory.get(i).getClose());
        }

        // 如果当前价格比最高价回落超过3%，则认为是显著回落
        return currentPrice < maxPrice * 0.97;
    }
} 